home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d18 / 360x480.arc / VGA < prev   
Text File  |  1991-04-28  |  7KB  |  240 lines

  1. /* I don't have Turbo Pascal, but I wanted to see what these looked like,
  2.    and whether or not they worked on my VGA.  I've got a clone VGA with a
  3.    "Trident" bios.  I've got 512 K.  Does anyone know how to do a similar
  4.    trick that gets me 640x480x256?  Or even 640x400x256 for those of us
  5.    without 512K VGAs?
  6.    -- russ (nelson@clutx [.bitnet | .clarkson.edu])
  7.    Live up to the light thou hast, and more will be granted thee.
  8.  
  9. */
  10.  
  11. #include <dos.h>
  12.  
  13. /*
  14. >From Hoke@cup.portal.com Mon Oct 30 09:52:08 1989
  15. From: Hoke@cup.portal.com (Hoke S Johnson)
  16. Newsgroups: comp.graphics
  17. Subject: VGA 360x480x256 mode usage code examples
  18. Date: 30 Oct 89 06:48:05 GMT
  19. Organization: The Portal System (TM)
  20.  
  21. Since I received a large number of requests for code examples on how
  22. to set and use the 360x480x256 color mode on the VGA card I am posting
  23. some Turbo Pascal Code routines and code fragments that demonstrate
  24. the use of this mode.  I have also included a 320x400x256 color mode
  25. set as well which is very similar to the 360x480x256 color mode.  This
  26. code has been tried on the Compaq VGA card and on the Orchid Designer
  27. VGA card and it works on both.  I cannot guarantee the suitability of
  28. this code for any particular VGA card but believe that it will work
  29. fine for all register level compatible VGA cards.  Have fun and enjoy.
  30.  
  31.  
  32. The following VGA 360x480x256 mode set procedure was converted from assembly
  33. language code which appeared in the Sept/Oct 1989 Programmer's Journal
  34. Volume 7.5 in an article by Michael Abrash,  who received the 360x480x256
  35. mode set code from John Bridges who has placed them in the public domain.
  36. The conversion from assembly language to Turbo Pascal Version 5.0 was
  37. done by Hoke Johnson.
  38. */
  39.  
  40.  
  41. #define    VGAPage    0xA000            /* VGA video RAM segment address */
  42.  
  43.  
  44. /* Procedure to set standard VGA card into 360x480x256 color mode */
  45. void VGA360x480()
  46. {
  47.     char         Inbyte;
  48.  
  49.     _AX = 0x0013;
  50.     geninterrupt(0x10);        /* Let the bios set up into 320x200x256 mode first */
  51.  
  52.     outportb(0x3c4, 0x04);
  53.     outportb(0x3c5, 0x06);        /* Disable chain 4 */
  54.  
  55.  
  56. /* Clear out the display memory, this did not appear in the Journal article */
  57.  
  58.     outportb(0x3c4, 0x02);
  59.     outportb(0x3c5, 0x0F);
  60.  
  61.     memset(MK_FP(VGAPage,0), 0, 65535);
  62.  
  63.     /* The following Sync reset was included in the Programmer's Journal
  64.     article, but I had to disable it since it causes all of my PCs to hang
  65.     when I include it */
  66.  
  67. #if 0
  68.     outportb($3c4,  $00);
  69.     outportb($3c5,  $01);
  70. #endif
  71.     /* Sync reset */
  72.     outportb(0x3c2, 0xE7);        /* Use the 28mHz clock */
  73.  
  74.     outportb(0x3d4, 0x11);
  75.     Inbyte = inportb(0x3d5) & 0x7f;
  76.     outportb(0x3d4, 0x11);
  77.     outportb(0x3d5, Inbyte);    /* Enable the writing of CRTC Registers */
  78.  
  79. /* Write the CRTC Registers */
  80.  
  81.     outportb(0x3d4, 0x00);
  82.     outportb(0x3d5, 0x6b);
  83.  
  84.     outportb(0x3d4, 0x01);
  85.     outportb(0x3d5, 0x59);
  86.  
  87.     outportb(0x3d4, 0x02);
  88.     outportb(0x3d5, 0x5a);
  89.  
  90.     outportb(0x3d4, 0x03);
  91.     outportb(0x3d5, 0x8e);
  92.  
  93.     outportb(0x3d4, 0x04);
  94.     outportb(0x3d5, 0x5e);
  95.  
  96.     outportb(0x3d4, 0x05);
  97.     outportb(0x3d5, 0x8a);
  98.  
  99.     outportb(0x3d4, 0x06);
  100.     outportb(0x3d5, 0x0d);
  101.  
  102.     outportb(0x3d4, 0x07);
  103.     outportb(0x3d5, 0x3e);
  104.  
  105.     outportb(0x3d4, 0x09);
  106.     outportb(0x3d5, 0x40);
  107.  
  108.     outportb(0x3d4, 0x10);
  109.     outportb(0x3d5, 0xea);
  110.  
  111.     outportb(0x3d4, 0x12);
  112.     outportb(0x3d5, 0xdf);
  113.  
  114.     outportb(0x3d4, 0x13);
  115.     outportb(0x3d5, 0x2d);
  116.  
  117.     outportb(0x3d4, 0x14);
  118.     outportb(0x3d5, 0x00);
  119.  
  120.     outportb(0x3d4, 0x15);
  121.     outportb(0x3d5, 0xe7);
  122.  
  123.     outportb(0x3d4, 0x16);
  124.     outportb(0x3d5, 0x06);
  125.  
  126.     outportb(0x3d4, 0x17);
  127.     outportb(0x3d5, 0xe3);
  128.  
  129.     outportb(0x3d4, 0x11);
  130.     outportb(0x3d5, 0xac);
  131. }
  132.  
  133. /*
  134.  
  135. The following code fragment shows how to write an arbitrary scanline
  136. of pixels on the screen in 360x480x256 VGA mode.  The Linenumbers are
  137. numbered from 0 to 479 starting from the upper left.  A byte array
  138. (Scanline) contains the pixels to be displayed.
  139.  
  140. I,J,K,L are Words or Integers
  141. BT is a Byte
  142.  
  143. I := Linenumber * 90;  {The start of each graphic scan line is 360/4 or 90
  144.                         memory addresses after the previous scan line.
  145.                         Each scan line occupies 90 bytes of address space
  146.                         and since there are four memory planes there are
  147.                         90 X 4 bytes of memory (360) for each scan line.
  148.  
  149.                         If the upper left pixel is pixel number 0,  and
  150.                         the lower right pixel is pixel number
  151.                         360x480-1, an arbitrary pixel is accessed by
  152.                         finding the VGA memory address which is the
  153.                         pixel number shifted right 2 places relative
  154.                         to the start of VGA memory and the memory
  155.                         plane number is the 2 LSBs of the pixel
  156.                         number}
  157.  
  158.  
  159.   For J := 0 to DispWidth - 1 do
  160.     Begin
  161.       L := I + j div 4;               {Calculate VGA memory address offset}
  162.       k := j mod 4;                   {Set K = 2 LSBs of pixel number}
  163.       BT := $01 shl k;                {Set BT = memory plane mask code}
  164.       Port[$3c4] := $02;              {Index Timing Sequencer register 2}
  165.       Port[$3c5] := BT;               {Write memory plane select mask}
  166.       Mem[VGAPage:L] := ScanLine[j];  {Write pixel}
  167.     End;
  168.  
  169. The following routine sets the standard VGA into 320x400x256 mode, which
  170. is very similar to the 360x480x256 mode.  Writing to the screen in
  171. 320x400x256 is the same as 360x480x256 mode, the only difference is
  172. the address span of each scan line which is 80 rather than 90.
  173.  
  174. */
  175.  
  176.  
  177. void VGA320x400()
  178. {
  179.     char         Inbyte;
  180.  
  181.     _AX = 0x0013;
  182.     geninterrupt(0x10);
  183.  
  184.     outportb(0x3c4, 0x04);
  185.     outportb(0x3c5, 0x06);        /* Disable chain 4 */
  186.  
  187.     outportb(0x3c4, 0x02);
  188.     outportb(0x3c5, 0x0F);
  189.  
  190.     memset(MK_FP(VGAPage,0), 0, 65535);
  191.  
  192.     outportb(0x3c2, 0xE3);        /* Set the 25mHz clock */
  193.  
  194.     outportb(0x3d4, 0x11);
  195.     Inbyte = inportb(0x3d5) & 0x7f;
  196.     outportb(0x3d4, 0x11);
  197.     outportb(0x3d5, Inbyte);    /* Enable the writing of CRTC Registers */
  198.  
  199.     outportb(0x3d4, 0x09);
  200.     outportb(0x3d5, 0x40);
  201.  
  202.     outportb(0x3d4, 0x14);
  203.     outportb(0x3d5, 0x00);
  204.  
  205.     outportb(0x3d4, 0x17);
  206.     outportb(0x3d5, 0xe3);
  207. }
  208.  
  209. void
  210. testpat(int x,int y)
  211. {
  212.     int i,j;
  213.     int k;
  214.     char far *cp;
  215.  
  216.     outportb(0x3c4, 2);
  217.     for (j = 0; j < y; j++) {
  218.         k = j * (x >> 2);
  219.         for (i = 0; i < x; i++) {
  220.             outportb(0x3c5, 1 << (i & 3));
  221.             cp = MK_FP(VGAPage,k + (i >> 2));
  222.             *cp = (i + j);
  223.         }
  224.     }
  225. }
  226.  
  227.  
  228. main()
  229. {
  230.     VGA320x400();
  231.     testpat(320,400);
  232.     getch();
  233.     VGA360x480();
  234.     testpat(360,480);
  235.     getch();
  236.     _AX = 0x0003;
  237.     geninterrupt(0x10);
  238. }
  239.